<?php
declare (strict_types = 1);

namespace app\controller;


use app\model\OrderGoods;
use app\Request;
use app\validate\CheckGoods;
use app\validate\CheckPay;
use Matrix\Exception;
use think\facade\Db;
use think\exception\ValidateException;
use think\facade\Log;

class Order
{
    /**
     * @param Request $request
     * @param string $id
     * @return string|\think\response\Redirect
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * 向订单表中添加数据及在订单商品表中添加数据
     */
    public function addOrder(Request $request,$id=''){
//        捕获异常
        try {
//            独立验证器
            validate(CheckGoods::class)->check($request->post('','','remove_xss'));
        }catch (ValidateException $exception){
//            返回错误
            return $exception->getMessage();
        }
//        接收前端的值
        $data=$request->post();
//        判断id是否有误
        if(!is_numeric($id)||$id==0){
            return '参数有误';
        }
//        判断是否登陆
        if(!session('?userInfo')){
//            存入回调标识
            session('goods_id',$id);
//            跳转到登陆页面
            return redirect('loginShow')->remember();
        }
//            启动事务
        Db::startTrans();
        try {
//            生成订单号
            $orderSn=getOrderSn();
//            在session中存一份
            session('orderSn',$orderSn);
//        组装订单号的数据
            $orderData=[
                'order_sn'=>$orderSn,
                'user_id'=>session('userInfo.id')
            ];
//        将值添加到订单表中
            $orderArray=(new \app\model\Order())->addOrder($orderData);
//        获取当前添加进去的订单id
            $orderId=$orderArray->toArray()['id'];
//        组装订单商品表的数据
            $orderGoodsData=[
                'goods_id'=>$id,
                'goods_price'=>$data['goods_price'],
                'goods_number'=>$data['number'],
                'order_id'=>$orderId
            ];
//        向订单商品表中添加数据
            (new OrderGoods())->addOrderGoods($orderGoodsData);
            // 提交事务
            Db::commit();
//            跳转到订单页面
            return redirect('/getOrderInfo');
        }catch (Exception $exception){
            // 回滚事务
            Db::rollback();
            return '下单失败';
        }
    }


    /**
     * @return \think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * 订单展示页面
     */
    public function getOrderInfo(){
//        获取订单号
        $orderSn=session('orderSn');
//        根据订单号查询商品数据
        $goodsData=(new \app\model\Order())->with(['orderGoodsData','orderGoodsData.goodsData'])->where('order_sn',$orderSn)->where('order_state',0)->find();
//        算出总价
        $totalPrice=0;
        foreach($goodsData['orderGoodsData'] as $val){
            $totalPrice+=$val['goods_price']*$val['goods_number'];
        }
//        将值展示到视图层
        return view('index/getOrderInfo',['goodsData'=>$goodsData,'totalPrice'=>$totalPrice]);
    }


    /**
     * @param Request $request
     * @return string|void
     * 支付页面
     */
    public function pay(Request $request){
//        判断是否在一分钟内连续点击
        if(!empty(cache('pay'))){
            return '不要连续点击支付按钮,请稍后再试';
        }
        try {
//            独立验证器
            validate(CheckPay::class)->check($request->post());
        }catch (Exception $exception){
//            返回错误
            return $exception->getMessage();
        }
        try {
//        接收值
            $data=$request->post();
//            存入缓存，防止重复点击立即支付
            cache('pay',time(),60);
//        调起支付页面
            return pay($data['orderSn'],$data['totalPrice']);
        }catch (Exception $exception){
            return '网络波动';
        }
    }


    public function callback(){
//        接收回调的参数
        $data=input();
//        对数据进行验签
        require_once("./plugins/alipay/config.php");
        require_once './plugins/alipay/pagepay/service/AlipayTradeService.php';
        $alipaySevice = new \AlipayTradeService($config);
        $result = $alipaySevice->check($data);
//        判断数据是否有误，没有错误则代表支付成功
        if(!$result){
            return '有危险，谨防钓鱼网站';
        }
//        调用模型层进行更改订单状态
        (new \app\model\Order())->changeState($data['out_trade_no']);
        Log::record('支付成功');
        return '订单已完成,请耐心等待发货';
    }
}
